package com.jimple.apps.RssClient.ui;

import java.io.File;
import java.io.FileWriter;
import java.util.Collection;
import java.util.HashMap;
import java.util.Properties;

import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.custom.StackLayout;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.events.ShellListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.ToolTip;
import org.eclipse.swt.widgets.Tray;
import org.eclipse.swt.widgets.TrayItem;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;

import com.jimple.apps.RssClient.Properties.LoadFeeds;
import com.jimple.apps.RssClient.Properties.LoadProperties;
import com.jimple.apps.RssClient.backend.Reader;
import com.sun.syndication.feed.synd.SyndEntry;

public class UiSetup {

	private boolean minInsteadOfClose = false;
	Shell shell;
	Display display;
	Browser browser;
	HashMap urlMap;
	private StackLayout layout;
	private Composite mainSpaceComp;
	Reader reader;
	private Table propertiesTable;
	private Collection urls;
	private Button refreshButton;
	private String currentLink;
	private Tree tree;
	private Label titleLabel;
	private TreeItem currentSite;
	private Composite propertiesComposite;
	Image image;
	private TrayItem trayItem;
	private boolean feedRefreshNeeded;

	public void setFeedRefreshNeeded(boolean feedRefreshNeeded) {
		this.feedRefreshNeeded = feedRefreshNeeded;
	}

	public UiSetup(Properties feedEntries) {
		this.urls = feedEntries.values();
		urlMap = new HashMap();
		display = new Display();
		shell = new Shell(display);
		Menu m = setupMenu();

		shell.setMenuBar(m);

		shell.addShellListener(new shellListener());

		shell.setLayout(new GridLayout());

		if (new File("ico.png").exists()) {
			image = new Image(display, "ico.png");
		}

		setupTray();

		Composite parent = new Composite(shell, SWT.NONE);
		parent.setLayout(new GridLayout());
		parent.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

		GridLayout groupGL = new GridLayout();
		groupGL.numColumns = 10;
		groupGL.makeColumnsEqualWidth = false;
		groupGL.horizontalSpacing = 10;
		parent.setLayout(groupGL);
		parent.setLayoutData(new GridData(GridData.FILL_BOTH));

		refreshButton = new Button(parent, SWT.NONE);
		refreshButton.setText("Refresh");
		refreshButton.addMouseListener(new MouseListener() {
			public void mouseDoubleClick(MouseEvent arg0) {
			}

			public void mouseDown(MouseEvent arg0) {
			}

			public void mouseUp(MouseEvent arg0) {
				refreshTable(true);
			}
		});

		Label spanLabel = new Label(parent, SWT.NONE);
		GridData spanlabeldata = new GridData();
		spanlabeldata.horizontalSpan = 3;
		spanLabel.setLayoutData(spanlabeldata);

		titleLabel = new Label(parent, GridData.FILL_HORIZONTAL);
		GridData labeldata = new GridData(GridData.FILL_HORIZONTAL);
		labeldata.horizontalSpan = 6;
		titleLabel.setVisible(true);
		titleLabel.setLayoutData(labeldata);
		titleLabel.setText(" ");

		tree = new Tree(parent, SWT.BORDER | SWT.V_SCROLL | SWT.LINE_SOLID);
		tree.setHeaderVisible(true);
		TreeColumn column = new TreeColumn(tree, SWT.LEFT);
		column.setText("Feed");
		column.setWidth(300);
		GridData tabledata = new GridData(SWT.SCROLL_LINE | SWT.SCROLL_PAGE
				| GridData.FILL_VERTICAL);
		tabledata.horizontalSpan = 3;
		tabledata.heightHint = 100;
		tabledata.widthHint = 200;
		tree.setLayoutData(tabledata);

		tree.addKeyListener(new KeyListener() {
			public void keyPressed(KeyEvent arg0) {
				if (arg0.keyCode == 13) {
					openCurrentLink();
				}
			}

			public void keyReleased(KeyEvent arg0) {
			}

		});
		tree.addMouseListener(new MouseListener() {
			public void mouseDoubleClick(MouseEvent arg0) {
				openCurrentLink();
			}

			public void mouseDown(MouseEvent arg0) {
			}

			public void mouseUp(MouseEvent arg0) {
			}

		});

		tree.addSelectionListener(new SelectionListener() {
			public void widgetDefaultSelected(SelectionEvent arg0) {
			}

			public void widgetSelected(SelectionEvent arg0) {
				try {
					TreeItem ti = (TreeItem) arg0.item;
					String urlKey = ti.getText();
					if (!urlMap.containsKey(urlKey)) {
						return;
					}
					SyndEntry entry = (SyndEntry) urlMap.get(urlKey);
					String url = entry.getDescription().getValue();
					setCurrentLink(entry.getLink());
					titleLabel.setText(entry.getPublishedDate() + " - "
							+ entry.getTitle());
					String constructedUrl = constructUrlFromString(url);
					browser.setUrl(constructedUrl);
					browser.redraw();

				} catch (Exception e) {
					e.printStackTrace();
				}

			}

		});

		GridData browserData = new GridData(GridData.FILL_BOTH);
		browserData.widthHint = 300;
		browserData.horizontalSpan = 7;
		browserData.grabExcessHorizontalSpace = true;
		browserData.heightHint = 100;
		mainSpaceComp = new Composite(parent, SWT.BORDER);
		mainSpaceComp.setLayoutData(browserData);
		layout = new StackLayout();
		mainSpaceComp.setLayout(layout);

		browser = new Browser(mainSpaceComp, SWT.BORDER);
		browser.setLayoutData(browserData);

		File welcomeUrl = new File("welcome.html");
		if (welcomeUrl.exists()) {
			browser.setUrl(welcomeUrl.toURI().toString());
		}
		GridData propdata = new GridData(GridData.FILL_BOTH);
		// propdata.widthHint = 300;
		// propdata.horizontalSpan = 7;
		propdata.grabExcessHorizontalSpace = true;
		// propdata.heightHint = 100;

		propertiesComposite = new Composite(mainSpaceComp, SWT.BORDER);
		propertiesComposite.setLayoutData(propdata);
		// GridData propertiesCompositeGD = new GridData(SWT.SCROLL_LINE
		// | SWT.SCROLL_PAGE | GridData.FILL_VERTICAL);
		// propertiesCompositeGD.horizontalSpan = 7;
		// propertiesComposite.setLayoutData(propertiesCompositeGD);
		GridLayout propertiesCompositeGL = new GridLayout();
		// propertiesCompositeGL.numColumns = 1;
		propertiesComposite.setLayout(propertiesCompositeGL);

		Button exitPropertiesButton = new Button(propertiesComposite, SWT.PUSH);
		exitPropertiesButton.setText("Exit Settings");
		exitPropertiesButton.addMouseListener(new MouseListener() {
			@Override
			public void mouseUp(MouseEvent arg0) {
				layout.topControl = browser;
				mainSpaceComp.layout();
			}

			public void mouseDoubleClick(MouseEvent arg0) {

			}

			public void mouseDown(MouseEvent arg0) {

			}
		});

		propertiesTable = new Table(propertiesComposite, SWT.BORDER
				| SWT.V_SCROLL | SWT.LINE_SOLID);
		propertiesTable.setHeaderVisible(true);
		TableColumn tcol = new TableColumn(propertiesTable, SWT.LEFT);
		tcol.setText("Setting");
		tcol.setWidth(300);
		TableColumn tcol2 = new TableColumn(propertiesTable, SWT.LEFT);
		tcol2.setText("Property");
		tcol2.setWidth(300);

		GridData tdata = new GridData(SWT.SCROLL_LINE | SWT.SCROLL_PAGE
				| GridData.FILL_BOTH);
		tabledata.horizontalSpan = 3;
		tabledata.heightHint = 100;
		tabledata.widthHint = 200;
		propertiesTable.setLayoutData(tdata);
		TableItem ti = new TableItem(propertiesTable, SWT.NONE);
		ti.setText(0, "property");
		ti.setText(1, "value");

		layout.topControl = browser;
		mainSpaceComp.layout();

	}

	public void setReader(Reader reader) {
		this.reader = reader;
	}

	public Tree getTree() {
		return tree;
	}

	private void refreshTable(boolean refresh) {
		if (refresh) {
			feedRefreshNeeded = true;
			refreshTable();
		}
	}

	private void refreshTable() {
		if (!feedRefreshNeeded) {
			return;
		}
		feedRefreshNeeded = false;
		tree.removeAll();
		Properties feeds = LoadFeeds.LoadFeeds();
		this.urls = feeds.values();
		Runnable runnable = new Reader(feeds, this, display);
		Thread thread = new Thread(runnable);
		thread.start();
	}

	public void redrawTable() {
		tree.redraw();
	}

	public void clearTable() {
		tree.removeAll();
	}

	public void allowRefresh(boolean allow) {
		refreshButton.setEnabled(allow);
	}

	public void openGui() {
		shell.setSize(800, 400);
		shell.setText("RssLight");

		shell.setImage(image);
		shell.setMaximized(true);
		shell.open();
		refreshTable(true);
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}

	}

	public TreeItem addSiteToTable(String item) {
		TreeItem titem = new TreeItem(tree, SWT.NONE);
		titem.setText(item);
		Color color = display.getSystemColor(SWT.COLOR_GRAY);
		titem.setBackground(color);
		currentSite = titem;
		return titem;

	}

	public TreeItem getCurrentSite() {
		return currentSite;
	}

	public void addItemToTable(TreeItem item, String subItem, SyndEntry entry) {
		TreeItem titem = new TreeItem(item, SWT.NULL);
		titem.setText(subItem);
		urlMap.put(subItem, entry);

	}

	public String getCurrentLink() {
		return currentLink;
	}

	public void setCurrentLink(String currentLink) {
		this.currentLink = currentLink;
	}

	private void setupTray() {
		try {

			Tray tray = display.getSystemTray();
			final ToolTip tip = new ToolTip(shell, SWT.BALLOON
					| SWT.ICON_INFORMATION);
			tip.setMessage("RSSLight 1.0\nAuthor: James White");

			if (tray != null) {
				trayItem = new TrayItem(tray, SWT.NONE);
				if (image != null) {
					trayItem.setImage(image);
				}
				trayItem.setToolTip(tip);
				final Menu menu = new Menu(shell, SWT.POP_UP);

				MenuItem menuItem = new MenuItem(menu, SWT.PUSH);
				menuItem.setText("Maximise");
				menuItem.addListener(SWT.Selection, new Listener() {
					public void handleEvent(Event arg0) {
						shell.setMinimized(false);
						shell.setVisible(true);
					}
				});

				menuItem = new MenuItem(menu, SWT.PUSH);
				menuItem.setText("About");
				menuItem.addListener(SWT.Selection, new Listener() {
					public void handleEvent(Event arg0) {
						tip.setVisible(true);
					}

				});
				menuItem = new MenuItem(menu, SWT.PUSH);
				menuItem.setText("Exit RSSLight");
				menuItem.addListener(SWT.Selection, new Listener() {
					public void handleEvent(Event arg0) {
						trayItem.dispose();
						shell.dispose();
						display.dispose();
					}
				});

				trayItem.addListener(SWT.MouseDoubleClick, new Listener() {
					public void handleEvent(Event arg0) {
						shell.setVisible(true);
						shell.setMinimized(false);
					}

				});

				trayItem.addListener(SWT.MenuDetect, new Listener() {
					public void handleEvent(Event event) {
						menu.setVisible(true);
					}
				});

			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public Label getTitleLabel() {
		return titleLabel;
	}

	public Menu setupMenu() {
		// create a file menu and add an exit item
		Menu m = new Menu(shell, SWT.BAR);
		final MenuItem file = new MenuItem(m, SWT.CASCADE);
		file.setText("&File");
		final Menu filemenu = new Menu(shell, SWT.DROP_DOWN);
		file.setMenu(filemenu);

		final MenuItem feedSettingsMenuItem = new MenuItem(filemenu, SWT.PUSH);
		feedSettingsMenuItem.setText("&Feed Settings");
		feedSettingsMenuItem.addSelectionListener(new SelectionListener() {
			public void widgetDefaultSelected(SelectionEvent arg0) {
			}

			public void widgetSelected(SelectionEvent arg0) {
				feedSettingsMenu();
			}

		});
		final MenuItem programSettingsMenu = new MenuItem(filemenu, SWT.PUSH);
		programSettingsMenu.setText("&RSSLight Settings");
		programSettingsMenu.addSelectionListener(new SelectionListener() {
			public void widgetDefaultSelected(SelectionEvent arg0) {

			}

			public void widgetSelected(SelectionEvent arg0) {
				try {
					loadSettings();
					layout.topControl = propertiesComposite;
					mainSpaceComp.layout();

				} catch (Exception e) {
					e.printStackTrace();
				}

			}

		});

		final MenuItem separator = new MenuItem(filemenu, SWT.SEPARATOR);
		final MenuItem exitMenuItem = new MenuItem(filemenu, SWT.PUSH);
		exitMenuItem.setText("E&xit");
		exitMenuItem.addSelectionListener(new SelectionListener() {

			@Override
			public void widgetSelected(SelectionEvent arg0) {
				trayItem.dispose();
				shell.dispose();
				display.dispose();
			}

			@Override
			public void widgetDefaultSelected(SelectionEvent arg0) {
				// TODO Auto-generated method stub

			}

		});
		return m;
	}

	private void loadSettings() {
		Properties settings = LoadProperties.LoadProperties();
	}

	public class shellListener implements ShellListener {
		public void shellActivated(ShellEvent arg0) {
		}

		public void shellClosed(ShellEvent arg0) {
			if (minInsteadOfClose) {
				arg0.doit = false;
				minimiseToTray(true);
			} else {
				trayItem.dispose();
				display.dispose();
			}
		}

		public void shellDeactivated(ShellEvent arg0) {
		}

		public void shellDeiconified(ShellEvent arg0) {
		}

		public void shellIconified(ShellEvent arg0) {
		}
	}

	private String constructUrlFromString(String url) {
		try {
			String tempdir = System.getenv("temp");
			File file = new File(tempdir, "openUrl.html");
			if (file.exists()) {
				int a = 0;
				while (!file.canWrite() && a < 10) {
					a++;
					System.err.println("cant write to file");
				}
				if (!file.delete()) {
					System.err.println("couldnt delete file");
				}
			}
			file.createNewFile();
			FileWriter fw = new FileWriter(file);
			fw.write(url);
			fw.close();
			String newUrl = file.toURI().toString();
			return newUrl;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;

	}

	public void minimiseToTray(boolean minimise) {
		shell.setMinimized(minimise);
		shell.setVisible(!minimise);
	}

	public void feedSettingsMenu() {
		FeedPropUI fpu = new FeedPropUI(display, this);
		fpu.launchGui();
		refreshTable();
	}

	private void openCurrentLink() {
		if (currentLink != null && !currentLink.equalsIgnoreCase("")) {
			browser.setUrl(currentLink);
			browser.redraw();
		}
	}

}
